home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- ;----------------------------------------------------------
- ; FTOE -- version for use with assembly language programs
- ;
- ; Copyright Bob Kline 1988
- ;
- ; Purpose:
- ; Convert floating point value to ASCII string using
- ; scientific notation.
- ;
- ; Input:
- ; DX:AX contain 4-byte real
- ; DI points to space for new string
- ; CX specifies precision
- ;
- ; Output:
- ; String stored at location pointed to by DI
- ;
- ; Registers changed:
- ; AX, BX, CX, DX, DI, SI
- ;
- ; Other procedures called:
- ; LDIV10
- ; FBINTODEC
- ;
- ; Comments:
- ; Calling procedure is responsible for making sure
- ; that there is enough space for the new string.
- ;----------------------------------------------------------
-
- PUBLIC FTOE
-
- EXTRN FBINTODEC:NEAR
- EXTRN LDIV10:NEAR
-
- .MODEL SMALL
-
- STRING EQU BYTE PTR [DI]
- POINTER EQU DI
- MAXPREC EQU 7
- PRECISION EQU CX
- EXPONENT EQU BX
- INDEX EQU SI
- DIGITS EQU DX
-
- .DATA?
- TEMPSTRING DB 11 DUP(?)
-
- .CODE
-
- FTOE PROC
-
- ; at the outset DX:AX = 4-byte real, DI points to start of output
- ; string, and CX has the specified precision to use
-
- ; bring precision into acceptable range
- CMP PRECISION,MAXPREC
- JLE L0
- MOV PRECISION,MAXPREC
- JMP SHORT L1
- L0: OR PRECISION,PRECISION
- JNS L1
- XOR PRECISION,PRECISION
-
- ; take care of zero as a special case by moving
- ; zeros into the temporary string, and jumping to
- ; the part where we move from the temporary string
- ; into the final output string; we put -7 into
- ; EXPONENT because the final exponent is calculated
- ; by the formula EXPONENT + DIGITS - 1, and we
- ; want it to come out as zero, right?
- L1: OR AX,AX
- JNZ L3
- OR DX,DX
- JNZ L3
- PUSH PRECISION
- MOV CX,8
- XOR INDEX,INDEX
- L2: MOV TEMPSTRING[SI],'0'
- INC SI
- LOOP L2
- POP PRECISION
- MOV EXPONENT,-7
- MOV DIGITS,8
- JMP SHORT L9A
-
- ; call fbintodec, which comes back with mantissa in DX:AX,
- ; sign in low bit of CX, and exponent in BX -- we'll check
- ; the sign immediately and take care of it so that CX will
- ; be free to pop the precision back off the stack
- L3: PUSH PRECISION
- PUSH POINTER
- CALL FBINTODEC
- POP POINTER
- OR CX,CX
- JZ L4
- MOV STRING,'-'
- INC POINTER
- L4:
-
- ; break down mantissa into a temporary string, using SI as the
- ; index to the string: note that the digits of the string will
- ; be stored backwards, that is, least significant first, so that
- ; when we go to move the digits into the output string, we'll
- ; pick them off from the end and work back to the beginning.
- ; The algorithm here is:
- ; while the mantissa is not zero
- ; divide by 10 and move the remainder into the string
- L7: XOR INDEX,INDEX
- PUSH EXPONENT
- JMP SHORT L9
- L10: CALL LDIV10
- OR BL,30h
- MOV TEMPSTRING[INDEX],BL
- INC INDEX
- L9: OR AX,AX
- JNZ L10
- OR DX,DX
- JNZ L10
- POP EXPONENT
- POP PRECISION
-
- ; round the mantissa if we need to
- MOV DIGITS,INDEX
- SUB INDEX,PRECISION
- DEC INDEX
- DEC INDEX
- JL L9A
- CMP TEMPSTRING[INDEX],'4'
- JLE L9A
- INC INDEX
- L11C: CMP TEMPSTRING[INDEX],'9'
- JE L11A
- INC TEMPSTRING[INDEX]
- JMP SHORT L9A
- L11A: MOV TEMPSTRING[INDEX],'0'
- L11: INC INDEX
- CMP INDEX,DIGITS
- JL L11C
- INC DIGITS
- INC INDEX
- MOV TEMPSTRING[INDEX],'1'
-
- ; get ready for some string moves
- L9A: CLD
- MOV INDEX,DIGITS
- DEC INDEX
-
- ; move one digit, then add a decimal point, followed by the rest
- ; of the digits; don't overshoot the precision -- on the other
- ; hand, if there aren't enough digits for the precision, fill
- ; up with zeros on the right
- MOV AL,TEMPSTRING[INDEX]
- STOSB
- OR PRECISION,PRECISION
- JZ L12
- MOV AL,'.'
- L13: STOSB
- DEC SI
- JS L13A
- MOV AL,TEMPSTRING[INDEX]
- JMP SHORT L13B
- L13A: MOV AL,'0'
- L13B: LOOP L13
-
- ; adjust the exponent: (exponent = exponent + digits - 1) and move
- ; it into the string
- L12: ADD EXPONENT,DIGITS
- DEC EXPONENT
- MOV AL,'e'
- STOSB
- MOV AL,'+'
- JGE L12A
- MOV AL,'-'
- NEG EXPONENT
- L12A: STOSB
- MOV AX,EXPONENT
- MOV CL,10
- DIV CL
- OR AX,3030h
- STOSB
- XCHG AH,AL
- STOSB
-
- ; terminate the string with a null byte and return from the procedure
- MOV AL,0
- STOSB
- RET
-
- FTOE ENDP
-
- END